#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <stdint.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdbool.h>
#include <errno.h>
#include <string.h>
#include <signal.h> // for signal()
#include <dlfcn.h>
#include <pthread.h>
#include <linux/fb.h>

int fd = open();
read(fd);
write(fd);

int cnt = 0;

void cleanup(int sig) // 函数头是固定，是回调函数，系统自动调用
{
    pid_t pid;
    while(1)
    {
        // 查看是否有进入僵尸态的子进程，若有直接回收，若没有直接退出
        if((pid=waitpid(-1, NULL, WNOHANG)) > 0)
            printf("cnt: %d(%d已退出)\n", ++cnt, pid);
        else
            break;
    }
}

int main(int argc, char const *argv[])
{
    int n;
    scanf("%d", &n);

    // 产生n个子进程
    pid_t a;
    for(int i=0; i<n; i++)
    {
        a = fork();
        if(a > 0)
        {
            printf("%d已创建\n", a);
            continue;
        }
        else 
            break;
    }

    if(a > 0)
    {
        // 当收到SIGCHLD时要取释放子进程的资源
        // 作用：将信号及其处理函数相关联（注册SIGCHLD的处理函数）
        // 即：告诉系统，将来收到 SIGCHLD 的时候去执行cleanup
        signal(SIGCHLD, cleanup);

        while(1)
            pause();
    }

    // 子进程直接退出变成僵尸，默认会自动向父进程发送 SIGCHILD
    return 0;
}
